<template>
	<div class="page-container">
		<el-card class="page-card">
			<el-form ref="queryForm" slot="header" :inline="true" :model="queryParams" label-width="75px">
				<el-form-item label="菜单名称:" prop="menuName">
					<el-input v-model.trim="queryParams.menuName" clearable placeholder="请输入菜单名称" @keyup.enter.native="handleQuery" />
				</el-form-item>
				<el-form-item label="菜单状态:" prop="status">
					<el-select v-model.trim="queryParams.status" clearable placeholder="请选择菜单状态">
						<el-option :value="undefined" label="全部" />
						<el-option v-for="dict in statusOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
					</el-select>
				</el-form-item>
				<el-form-item>
					<div class="page-search-btn">
						<el-button icon="el-icon-search" type="primary" @click="handleQuery">搜索</el-button>
						<el-button icon="el-icon-refresh" type="primary" plain @click="resetQuery">重置</el-button>
					</div>
				</el-form-item>
			</el-form>
			<div class="page-card-options">
				<el-button v-hasPermi="['system:menu:add']" icon="el-icon-plus" type="primary" @click="handleAdd">新增 </el-button>
			</div>

			<el-table v-loading="loading" :data="menuList" :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" row-key="menuId" stripe>
				<el-table-column :formatter="emptyToString" align="center" label="序号" type="index" width="55" />
				<el-table-column :formatter="emptyToString" :show-overflow-tooltip="true" label="菜单名称" prop="menuName" width="160"></el-table-column>
				<el-table-column :formatter="emptyToString" align="center" label="图标" prop="icon" width="100">
					<template slot-scope="scope">
						<svg-icon :icon-class="scope.row.icon" />
					</template>
				</el-table-column>
				<el-table-column :formatter="emptyToString" align="center" label="排序" prop="orderNum" width="60"></el-table-column>
				<el-table-column :formatter="emptyToString" :show-overflow-tooltip="true" align="center" label="权限标识" prop="perms"></el-table-column>
				<el-table-column :formatter="emptyToString" :show-overflow-tooltip="true" align="center" label="组件路径" prop="component"></el-table-column>
				<el-table-column :formatter="statusFormat" label="状态" prop="status" width="80"></el-table-column>
				<el-table-column :formatter="emptyToString" align="center" label="创建时间" min-width="156" prop="createTime">
					<template slot-scope="scope">
						<span>{{ parseTime(scope.row.createTime) }}</span>
					</template>
				</el-table-column>
				<el-table-column :width="tableAction" align="center" fixed="right" header-align="center" label="操作">
					<template slot-scope="scope">
						<div class="table-action flex justify-center">
							<el-dropdown @command="handleCommand($event, scope.row)">
								<el-button type="primary"> 更多<i class="el-icon-arrow-down el-icon--right"></i> </el-button>
								<el-dropdown-menu slot="dropdown">
									<el-dropdown-item v-hasPermi="['system:menu:edit']" command="handleUpdate">编辑</el-dropdown-item>
									<el-dropdown-item v-hasPermi="['system:menu:add']" command="handleAdd">新增</el-dropdown-item>
									<el-dropdown-item v-hasPermi="['system:menu:remove']" command="handleDelete">删除</el-dropdown-item>
								</el-dropdown-menu>
							</el-dropdown>
						</div>
					</template>
				</el-table-column>
			</el-table>
		</el-card>
		<!-- 添加或编辑菜单对话框 -->
		<l-dialog v-model="open" :title="title" width="600px" @close="cancel" @formClose="cancel" @formSubmit="submitForm">
			<el-form ref="form" :model="form" :rules="rules" label-width="100px">
				<el-row>
					<el-col :span="24">
						<el-form-item label="上级菜单:">
							<treeselect v-model.trim="form.parentId" :normalizer="normalizer" :options="menuOptions" :show-count="true" class="!w-[299px] !max-w-[299px]" placeholder="选择上级菜单" />
						</el-form-item>
					</el-col>
					<el-col :span="24">
						<el-form-item label="菜单类型:" prop="menuType">
							<el-radio-group v-model.trim="form.menuType" class="!w-[299px] !max-w-[299px]">
								<el-radio label="M">目录</el-radio>
								<el-radio label="C">菜单</el-radio>
								<el-radio label="F">按钮</el-radio>
							</el-radio-group>
						</el-form-item>
					</el-col>
					<el-col :span="24">
						<el-form-item v-if="form.menuType != 'F'" label="菜单图标:">
							<el-popover placement="bottom-start" trigger="click" width="460" @show="$refs['iconSelect'].reset()">
								<IconSelect ref="iconSelect" @selected="selected" />
								<el-input slot="reference" v-model.trim="form.icon" placeholder="点击选择图标">
									<svg-icon v-if="form.icon" slot="prefix" :icon-class="form.icon" class="el-input__icon" style="height: 32px; width: 16px" />
									<i v-else slot="prefix" class="el-icon-search el-input__icon" />
								</el-input>
							</el-popover>
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item label="菜单名称:" prop="menuName">
							<el-input v-model.trim="form.menuName" class="!w-[299px] !max-w-[299px]" placeholder="请输入菜单名称" />
						</el-form-item>
					</el-col>
					<el-col :span="24">
						<el-form-item label="显示排序:" prop="orderNum">
							<el-input-number v-model.trim="form.orderNum" :min="0" class="!w-[299px] !max-w-[299px]" controls-position="right" />
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item v-if="form.menuType != 'F'" label="是否外链:">
							<el-radio-group v-model.trim="form.isFrame" class="!w-[299px] !max-w-[299px]">
								<el-radio label="0">是</el-radio>
								<el-radio label="1">否</el-radio>
							</el-radio-group>
						</el-form-item>
					</el-col>
					<el-col :span="24">
						<el-form-item v-if="form.menuType != 'F'" label="路由地址:" prop="path">
							<el-input v-model.trim="form.path" class="!w-[299px] !max-w-[299px]" placeholder="请输入路由地址" />
						</el-form-item>
					</el-col>
					<el-col v-if="form.menuType == 'C'" :span="24">
						<el-form-item label="组件路径:" prop="component">
							<el-input v-model.trim="form.component" class="!w-[299px] !max-w-[299px]" placeholder="请输入组件路径" />
						</el-form-item>
					</el-col>
					<el-col :span="24">
						<el-form-item v-if="form.menuType != 'M'" label="权限标识:">
							<el-input v-model.trim="form.perms" class="!w-[299px] !max-w-[299px]" maxlength="50" placeholder="请权限标识" />
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item v-if="form.menuType != 'F'" label="显示状态:">
							<el-radio-group v-model.trim="form.visible" class="!w-[299px] !max-w-[299px]">
								<el-radio v-for="dict in visibleOptions" :key="dict.dictValue" :label="dict.dictValue">{{ dict.dictLabel }} </el-radio>
							</el-radio-group>
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item v-if="form.menuType != 'F'" label="菜单状态:">
							<el-radio-group v-model.trim="form.status" class="!w-[299px] !max-w-[299px]">
								<el-radio v-for="dict in statusOptions" :key="dict.dictValue" :label="dict.dictValue">{{ dict.dictLabel }} </el-radio>
							</el-radio-group>
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item v-if="form.menuType == 'C'" label="是否缓存:">
							<el-radio-group v-model.trim="form.isCache" class="!w-[299px] !max-w-[299px]">
								<el-radio label="0">缓存</el-radio>
								<el-radio label="1">不缓存</el-radio>
							</el-radio-group>
						</el-form-item>
					</el-col>
				</el-row>
			</el-form>
		</l-dialog>
	</div>
</template>

<script>
import { addMenu, delMenu, getMenu, listMenu, updateMenu } from '@/api/system/menu';
import Treeselect from '@riophae/vue-treeselect';
import '@riophae/vue-treeselect/dist/vue-treeselect.css';
import IconSelect from '@/components/IconSelect';
import tableMixins from '@/mixins/table';

export default {
	name: 'Menu',
	components: { Treeselect, IconSelect },
	mixins: [tableMixins],
	data() {
		return {
			// 遮罩层
			loading: true,
			// 显示搜索条件
			showSearch: true,
			// 菜单表格树数据
			menuList: [],
			// 菜单树选项
			menuOptions: [],
			// 弹出层标题
			title: '',
			// 是否显示弹出层
			open: false,
			// 显示状态数据字典
			visibleOptions: [],
			// 菜单状态数据字典
			statusOptions: [],
			// 查询参数
			queryParams: {
				menuName: undefined,
				visible: undefined,
			},
			// 表单参数
			form: {},
			// 表单校验
			rules: {
				menuName: [{ required: true, message: '菜单名称不能为空', trigger: 'blur' }],
				orderNum: [{ required: true, message: '菜单顺序不能为空', trigger: 'blur' }],
				path: [{ required: true, message: '路由地址不能为空', trigger: 'blur' }],
			},
		};
	},
	created() {
		this.getList();
		this.getDicts('sys_show_hide').then((response) => {
			this.visibleOptions = response.data;
		});
		this.getDicts('sys_normal_disable').then((response) => {
			this.statusOptions = response.data;
		});
	},
	methods: {
		// 选择图标
		selected(name) {
			this.form.icon = name;
		},
		/** 查询菜单列表 */
		getList() {
			this.loading = true;
			listMenu(this.queryParams)
				.then((response) => {
					this.menuList = this.handleTree(response.data, 'menuId');
					this.setActionWidth();
				})
				.finally(() => {
					this.loading = false;
				});
		},
		/** 转换菜单数据结构 */
		normalizer(node) {
			if (node.children && !node.children.length) {
				delete node.children;
			}
			return {
				id: node.menuId,
				label: node.menuName,
				children: node.children,
			};
		},
		/** 查询菜单下拉树结构 */
		getTreeselect() {
			listMenu().then((response) => {
				this.menuOptions = [];
				const menu = { menuId: 0, menuName: '主类目', children: [] };
				menu.children = this.handleTree(response.data, 'menuId');
				this.menuOptions.push(menu);
			});
		},
		// 显示状态字典翻译
		visibleFormat(row, column) {
			if (row.menuType == 'F') {
				return '';
			}
			return this.selectDictLabel(this.visibleOptions, row.visible);
		},
		// 菜单状态字典翻译
		statusFormat(row, column) {
			if (row.menuType == 'F') {
				return '';
			}
			return this.selectDictLabel(this.statusOptions, row.status);
		},
		// 取消按钮
		cancel() {
			this.open = false;
			this.reset();
		},
		// 表单重置
		reset() {
			this.form = {
				menuId: undefined,
				parentId: 0,
				menuName: undefined,
				icon: undefined,
				menuType: 'M',
				orderNum: undefined,
				isFrame: '1',
				isCache: '0',
				visible: '0',
				status: '0',
			};
			this.resetForm('form');
		},
		/** 搜索按钮操作 */
		handleQuery() {
			this.getList();
		},
		/** 重置按钮操作 */
		resetQuery() {
			this.resetForm('queryForm');
			this.handleQuery();
		},
		/** 新增按钮操作 */
		handleAdd(row) {
			this.reset();
			this.getTreeselect();
			if (row != null && row.menuId) {
				this.form.parentId = row.menuId;
			} else {
				this.form.parentId = 0;
			}
			this.open = true;
			this.title = '添加菜单';
		},
		/** 编辑按钮操作 */
		handleUpdate(row) {
			this.reset();
			this.getTreeselect();
			getMenu(row.menuId).then((response) => {
				this.form = response.data;
				this.open = true;
				this.title = '编辑菜单';
			});
		},
		/** 提交按钮 */
		submitForm: function () {
			this.$refs['form'].validate((valid) => {
				if (valid) {
					if (this.form.menuId != undefined) {
						updateMenu(this.form).then(() => {
							this.msgSuccess('编辑成功');
							this.open = false;
							this.getList();
						});
					} else {
						addMenu(this.form).then(() => {
							this.msgSuccess('新增成功');
							this.open = false;
							this.getList();
						});
					}
				}
			});
		},
		/** 删除按钮操作 */
		handleDelete(row) {
			this.$confirm('是否确认删除名称为"' + row.menuName + '"的数据项?', '警告', {
				confirmButtonText: '确定',
				cancelButtonText: '取消',
				type: 'warning',
			})
				.then(function () {
					return delMenu(row.menuId);
				})
				.then(() => {
					this.getList();
					this.msgSuccess('删除成功');
				});
		},
		handleCommand(key, row) {
			this[key](row);
		},
	},
};
</script>
